09. 싱글톤 컨테이너
09. 싱글톤 컨테이너
싱글톤 컨테이너
스프링은 일반적으로 웹 용 컨테이너
- 일반적으로 전부 웹 어플리케이션
- 일반적으로 웹은 다수의 사용자가 사용함
- A, B, C가 동시에 요청을 하면?
- DI는 어떤식으로?
- 기존의
AppConfig
는 지속적으로 객체를 생성한다. - 트래픽이 초당 100이라면? → 100개의 객체를 생성 → 시스템 부하
- 하나의 인스턴스만 생성해서 계속 사용한다면?
싱글톤 패턴
- 클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴
- 생성자의
private
로 한다. - static 영역에 자기 자신을 객체로 만들어 저장한다.
- 필요로 할때마다
getInstance()
를 사용해 객체를 가져온다.
- 필요로 할때마다
싱글톤 패턴의 문제점
- 구현 코드 복잡
- 의존 관계상 클라이언트가 구제 클래스에 의존 → DIP 위반
- 테스트 어려움
- 클라이언트가 구체 클래스에 의존 → OCP 위반 가능성 높음
- 상속 불가
- 유연성 감소
싱글톤 컨테이너
Spring은 싱글톤 패턴의 문제점은 해결하고 객체 인스턴스를 싱글톤으로 관리한다.
- Bean은 대표적인 싱글톤
- 컨테이너는 하나의 객체만 생성
- 싱글톤의 단점을 해결하고 장점만 살릴 수 있다.
- 싱글톤 패턴을 위한 지저분한 생성자 코드의 생략
- DIP와 OCP에서 안전하게 자유롭게 싱글톤 사용 가능
싱글톤 방식의 주의점
- 싱글톤을 어떤식으로 만들던, 객체 인스턴스가 공유되기에 싱글톤 객체는 상태를 유지하게 설계되면 안된다.
- 무상태(stateless)로 해야한다.
- 특정 클라이언트에 의존되서는 안된다.
- 특정 클라이언트가 값을 변경 할 수 있는 필드가 있으면 안된다!
- Read 기능만 사용하는게 좋다.
- 필드 대신에 자바에서 공유되지 않는 지역변수, 파라미터, ThreadLocal 등을 지향
- 만약 공유 변수가 있다면 큰일날 수도?
- 일반적인 스레드에서 일어나는 문제를 보게된다…
@Configuration과 싱글톤
- 우리가 만든
AppConfig
는 과연 싱글톤을 꺠지는 코드일까?
테스트
- 둘이 같은 객체로 생성된다. 모두 같은 Bean이다!
- Java 코드인데 어떻게 이런…?
@Configuraion과 바이트 코드 조막의 마법
스프링 컨테이너는 싱글톤 레지스트리이다. → 싱글톤의 보장
@Configuraion
을 붙인 클래스는 아래와 같이 보인다.- 내가 만든 AppConfig는 본래
class hello.core.AppConfig
로 등록되어야한다. - 근데 뒤에 이상한게 붙는다.
- 내가 만든 AppConfig는 본래
스프링은 내가 만든 AppConfig를 상속 받은 임의의 클래스를 추가로 만들어 그걸 빈으로 등록했다!
- CGLIB를 사용해 실제 컨테이너에는 내가 등록한 객체가 아닌 다른 객체가 들어가 있다.
- 이를 통해 @Bean이 붙은 메서드나 객체의 중복된 객체 생성을 체크해 로직을 통해 중복 생성을 방어하고 bean을 싱글톤 상태로 유지시킨다.
- 물론 자식 타입으로 저장 되기에 AppConfig으로 조회시에도 조회가 된다!
- AOP도 이러한 비슷한 로직을 실행한다.
그렇다면… @Configuration
없이 @Bean
만 적용한다면?
- 싱글톤이 꺠진다.
- 즉 Bean 등록은 되지만 싱글톤을 보장하지는 않는다.
- 항상 @Configuration을 사용하도록 하자…
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.